"""
工具管理器模块

负责管理所有工具的注册、配置和执行。
"""

import json
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Type

from rich.console import Console
from rich.table import Table

from .base import BaseTool, ToolResult, ToolError

console = Console()


class ToolManager:
    """工具管理器"""
    
    def __init__(self, config_dir: Optional[Path] = None):
        """
        初始化工具管理器
        
        Args:
            config_dir: 配置目录路径
        """
        self.config_dir = config_dir or Path.home() / '.minicoder'
        self.tools: Dict[str, BaseTool] = {}
        self.tool_configs: Dict[str, Dict[str, Any]] = {}
        self.execution_history: List[Dict[str, Any]] = []
        
        # 确保配置目录存在
        self.config_dir.mkdir(parents=True, exist_ok=True)
        
        # 加载配置
        self._load_config()
        
        # 注册默认工具
        self._register_default_tools()
    
    def _load_config(self) -> None:
        """加载工具配置"""
        config_file = self.config_dir / 'tools_config.json'
        if config_file.exists():
            try:
                with open(config_file, 'r', encoding='utf-8') as f:
                    self.tool_configs = json.load(f)
            except Exception as e:
                console.print(f"[yellow]警告: 无法加载工具配置: {e}[/yellow]")
    
    def _save_config(self) -> None:
        """保存工具配置"""
        config_file = self.config_dir / 'tools_config.json'
        try:
            with open(config_file, 'w', encoding='utf-8') as f:
                json.dump(self.tool_configs, f, ensure_ascii=False, indent=2)
        except Exception as e:
            console.print(f"[red]错误: 无法保存工具配置: {e}[/red]")
    
    def _register_default_tools(self) -> None:
        """注册默认工具"""
        # 延迟导入，避免循环导入
        from . import _get_default_tools
        
        for tool_class in _get_default_tools():
            try:
                tool = tool_class()
                self.register_tool(tool)
            except Exception as e:
                console.print(f"[yellow]警告: 无法注册工具 {tool_class.__name__}: {e}[/yellow]")
    
    def register_tool(self, tool: BaseTool) -> None:
        """
        注册工具
        
        Args:
            tool: 工具实例
        """
        self.tools[tool.name] = tool
        
        # 应用保存的配置
        if tool.name in self.tool_configs:
            tool.configure(self.tool_configs[tool.name])
        
        console.print(f"[green]✓[/green] 工具已注册: {tool.name}")
    
    def unregister_tool(self, tool_name: str) -> bool:
        """
        注销工具
        
        Args:
            tool_name: 工具名称
            
        Returns:
            bool: 是否成功注销
        """
        if tool_name in self.tools:
            del self.tools[tool_name]
            console.print(f"[yellow]工具已注销: {tool_name}[/yellow]")
            return True
        return False
    
    def get_tool(self, tool_name: str) -> Optional[BaseTool]:
        """
        获取工具
        
        Args:
            tool_name: 工具名称
            
        Returns:
            BaseTool: 工具实例，如果不存在则返回 None
        """
        return self.tools.get(tool_name)
    
    def list_tools(self, enabled_only: bool = False) -> List[BaseTool]:
        """
        列出所有工具
        
        Args:
            enabled_only: 是否只列出启用的工具
            
        Returns:
            List[BaseTool]: 工具列表
        """
        tools = list(self.tools.values())
        if enabled_only:
            tools = [tool for tool in tools if tool.is_enabled()]
        return tools
    
    def execute_tool(self, tool_name: str, **kwargs) -> ToolResult:
        """
        执行工具
        
        Args:
            tool_name: 工具名称
            **kwargs: 工具参数
            
        Returns:
            ToolResult: 执行结果
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return ToolResult(
                success=False,
                error=f"工具不存在: {tool_name}"
            )
        
        if not tool.is_enabled():
            return ToolResult(
                success=False,
                error=f"工具已禁用: {tool_name}"
            )
        
        start_time = datetime.now()
        
        try:
            # 记录执行历史
            execution_record = {
                'tool_name': tool_name,
                'timestamp': start_time.isoformat(),
                'parameters': kwargs,
                'status': 'running'
            }
            self.execution_history.append(execution_record)
            
            # 执行工具
            result = tool.execute(**kwargs)
            
            # 更新执行记录
            execution_record['status'] = 'completed' if result.success else 'failed'
            execution_record['execution_time'] = result.execution_time
            execution_record['result'] = result.to_dict()
            
            return result
            
        except Exception as e:
            # 更新执行记录
            if self.execution_history:
                self.execution_history[-1]['status'] = 'error'
                self.execution_history[-1]['error'] = str(e)
            
            return ToolResult(
                success=False,
                error=f"工具执行失败: {e}",
                execution_time=(datetime.now() - start_time).total_seconds()
            )
    
    def configure_tool(self, tool_name: str, config: Dict[str, Any]) -> bool:
        """
        配置工具
        
        Args:
            tool_name: 工具名称
            config: 配置字典
            
        Returns:
            bool: 是否成功配置
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return False
        
        tool.configure(config)
        self.tool_configs[tool_name] = config
        self._save_config()
        
        console.print(f"[green]✓[/green] 工具配置已更新: {tool_name}")
        return True
    
    def enable_tool(self, tool_name: str) -> bool:
        """
        启用工具
        
        Args:
            tool_name: 工具名称
            
        Returns:
            bool: 是否成功启用
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return False
        
        tool.enable()
        console.print(f"[green]✓[/green] 工具已启用: {tool_name}")
        return True
    
    def disable_tool(self, tool_name: str) -> bool:
        """
        禁用工具
        
        Args:
            tool_name: 工具名称
            
        Returns:
            bool: 是否成功禁用
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return False
        
        tool.disable()
        console.print(f"[yellow]工具已禁用: {tool_name}[/yellow]")
        return True
    
    def get_tool_info(self, tool_name: str) -> Optional[Dict[str, Any]]:
        """
        获取工具信息
        
        Args:
            tool_name: 工具名称
            
        Returns:
            Dict[str, Any]: 工具信息，如果不存在则返回 None
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return None
        
        return tool.get_info()
    
    def list_tool_parameters(self, tool_name: str) -> Optional[Dict[str, Dict[str, Any]]]:
        """
        列出工具参数
        
        Args:
            tool_name: 工具名称
            
        Returns:
            Dict[str, Dict[str, Any]]: 参数定义，如果工具不存在则返回 None
        """
        tool = self.get_tool(tool_name)
        if not tool:
            return None
        
        return tool.get_parameters()
    
    def get_execution_history(self, limit: int = 50) -> List[Dict[str, Any]]:
        """
        获取执行历史
        
        Args:
            limit: 返回记录数量限制
            
        Returns:
            List[Dict[str, Any]]: 执行历史
        """
        return self.execution_history[-limit:] if self.execution_history else []
    
    def clear_execution_history(self) -> None:
        """清空执行历史"""
        self.execution_history.clear()
        console.print("[yellow]执行历史已清空[/yellow]")
    
    def export_tool_config(self, file_path: Path) -> bool:
        """
        导出工具配置
        
        Args:
            file_path: 导出文件路径
            
        Returns:
            bool: 是否成功导出
        """
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(self.tool_configs, f, ensure_ascii=False, indent=2)
            
            console.print(f"[green]✓[/green] 工具配置已导出到: {file_path}")
            return True
        except Exception as e:
            console.print(f"[red]错误: 无法导出配置: {e}[/red]")
            return False
    
    def import_tool_config(self, file_path: Path) -> bool:
        """
        导入工具配置
        
        Args:
            file_path: 导入文件路径
            
        Returns:
            bool: 是否成功导入
        """
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                imported_configs = json.load(f)
            
            # 应用配置到现有工具
            for tool_name, config in imported_configs.items():
                if tool_name in self.tools:
                    self.tools[tool_name].configure(config)
            
            # 更新配置
            self.tool_configs.update(imported_configs)
            self._save_config()
            
            console.print(f"[green]✓[/green] 工具配置已从 {file_path} 导入")
            return True
        except Exception as e:
            console.print(f"[red]错误: 无法导入配置: {e}[/red]")
            return False
    
    def create_tools_table(self, enabled_only: bool = False) -> Table:
        """
        创建工具信息表格
        
        Args:
            enabled_only: 是否只显示启用的工具
            
        Returns:
            Table: Rich 表格对象
        """
        table = Table(title="🔧 可用工具", show_header=True, header_style="bold magenta")
        table.add_column("工具名称", style="cyan", no_wrap=True)
        table.add_column("描述", style="green")
        table.add_column("版本", style="blue")
        table.add_column("状态", style="yellow")
        table.add_column("参数数量", style="dim")
        
        tools = self.list_tools(enabled_only)
        for tool in tools:
            status = "✅ 启用" if tool.is_enabled() else "❌ 禁用"
            param_count = len(tool.get_parameters())
            
            table.add_row(
                tool.name,
                tool.description,
                tool.version,
                status,
                str(param_count)
            )
        
        return table
    
    def create_execution_history_table(self, limit: int = 20) -> Table:
        """
        创建执行历史表格
        
        Args:
            limit: 显示记录数量限制
            
        Returns:
            Table: Rich 表格对象
        """
        table = Table(title="📊 执行历史", show_header=True, header_style="bold magenta")
        table.add_column("时间", style="dim", no_wrap=True)
        table.add_column("工具", style="cyan")
        table.add_column("状态", style="yellow")
        table.add_column("执行时间", style="blue")
        table.add_column("参数", style="dim")
        
        history = self.get_execution_history(limit)
        for record in reversed(history):  # 最新的在前
            timestamp = record['timestamp'][:19]  # 只显示日期时间部分
            status = record.get('status', 'unknown')
            exec_time = f"{record.get('execution_time', 0):.2f}s"
            params = str(record.get('parameters', {}))[:50] + "..." if len(str(record.get('parameters', {}))) > 50 else str(record.get('parameters', {}))
            
            status_style = {
                'completed': 'green',
                'failed': 'red',
                'error': 'red',
                'running': 'yellow'
            }.get(status, 'dim')
            
            table.add_row(
                timestamp,
                record['tool_name'],
                f"[{status_style}]{status}[/{status_style}]",
                exec_time,
                params
            )
        
        return table
    
    def search_tools(self, query: str) -> List[BaseTool]:
        """
        搜索工具
        
        Args:
            query: 搜索查询
            
        Returns:
            List[BaseTool]: 匹配的工具列表
        """
        query_lower = query.lower()
        matching_tools = []
        
        for tool in self.tools.values():
            if (query_lower in tool.name.lower() or 
                query_lower in tool.description.lower()):
                matching_tools.append(tool)
        
        return matching_tools
    
    def get_tool_statistics(self) -> Dict[str, Any]:
        """
        获取工具统计信息
        
        Returns:
            Dict[str, Any]: 统计信息
        """
        total_tools = len(self.tools)
        enabled_tools = len([t for t in self.tools.values() if t.is_enabled()])
        disabled_tools = total_tools - enabled_tools
        
        # 按类型统计
        tool_types = {}
        for tool in self.tools.values():
            tool_type = tool.__class__.__module__.split('.')[-1].replace('_tools', '')
            tool_types[tool_type] = tool_types.get(tool_type, 0) + 1
        
        # 执行统计
        total_executions = len(self.execution_history)
        successful_executions = len([r for r in self.execution_history if r.get('status') == 'completed'])
        failed_executions = total_executions - successful_executions
        
        return {
            'total_tools': total_tools,
            'enabled_tools': enabled_tools,
            'disabled_tools': disabled_tools,
            'tool_types': tool_types,
            'execution_stats': {
                'total_executions': total_executions,
                'successful_executions': successful_executions,
                'failed_executions': failed_executions,
                'success_rate': (successful_executions / total_executions * 100) if total_executions > 0 else 0
            }
        }
